import dayjs from 'dayjs'
import { ElMessage } from 'element-plus'
import { useClipboard } from '@vueuse/core'
// import { removeConfigLayout } from "@/utils/cache/local-storage"

/** 格式化时间 */
export const formatDateTime = (time: string | number | Date) => {
  return time ? dayjs(new Date(time)).format('YYYY-MM-DD HH:mm:ss') : 'N/A'
}

/** 用 JS 获取全局 css 变量 */
export const getCssVariableValue = (cssVariableName: string) => {
  let cssVariableValue = ''
  try {
    // 没有拿到值时，会返回空串
    cssVariableValue = getComputedStyle(document.documentElement).getPropertyValue(cssVariableName)
  } catch (error) {
    console.error(error)
  }
  return cssVariableValue
}

/** 用 JS 设置全局 CSS 变量 */
export const setCssVariableValue = (cssVariableName: string, cssVariableValue: string) => {
  try {
    document.documentElement.style.setProperty(cssVariableName, cssVariableValue)
  } catch (error) {
    console.error(error)
  }
}

/** http没有clipboard 则只能用... useClipboard底层使用clipboard */
export const copyEvent = async (source: string) => {
  // 考虑到兼容性问题，
  // 先判断当前有没有clipboard实例，如果有，则使用useClipboard；如果没有，则使用js原生方法
  if (navigator.clipboard) {
    const { copy } = useClipboard({ source })
    copy(source)
  } else {
    const input = document.createElement('input')
    input.setAttribute('value', source)
    document.body.appendChild(input)
    input.select()
    document.execCommand('copy')
    document.body.removeChild(input)
  }
  ElMessage.success({ message: '复制成功' })
}

/** 格式化米与千米 */
export const formatMeter = (meter: number) => {
  if (meter >= 1000) {
    return (meter / 1000).toFixed(2) + 'km'
  } else {
    return meter.toFixed(2) + 'm'
  }
}

/**
 * Generates a random integer between minNum and maxNum (inclusive).
 * If only one argument is provided, it generates a number between 1 and minNum.
 * @param minNum - The minimum number or the only limit if maxNum is not provided.
 * @param maxNum - The maximum number.
 * @returns A random integer.
 */
export function randomExtend(minNum: number, maxNum?: number): number {
  if (maxNum === undefined) {
    return Math.floor(Math.random() * minNum + 1)
  } else {
    return Math.floor(Math.random() * (maxNum - minNum + 1) + minNum)
  }
}

/**
 * Creates a debounced version of a callback function.
 * @param delay - The delay in milliseconds.
 * @param callback - The function to debounce.
 * @returns A debounced function.
 */
export function debounce<T extends (...args: any[]) => any>(
  delay: number,
  callback: T,
): (...args: Parameters<T>) => void {
  let lastTime: ReturnType<typeof setTimeout>

  return function (this: any, ...args: Parameters<T>) {
    clearTimeout(lastTime)

    lastTime = setTimeout(() => {
      callback.apply(this, args)
    }, delay)
  }
}

/**
 * Observes changes to the DOM's style attribute and invokes a callback.
 * @param dom - The DOM element to observe.
 * @param callback - The callback function to invoke when changes occur.
 * @returns A MutationObserver instance to manage the observation.
 */
export function observerDomResize(dom: HTMLElement, callback: MutationCallback): MutationObserver {
  // MutationObserver is a modern API and is widely supported.
  const observer = new MutationObserver(callback)

  // Observe changes to the "style" attribute of the DOM element.
  observer.observe(dom, { attributes: true, attributeFilter: ['style'], attributeOldValue: true })

  return observer
}

/**
 * Calculates the Euclidean distance between two points in 2D space.
 * @param pointOne - The first point as a tuple [x, y].
 * @param pointTwo - The second point as a tuple [x, y].
 * @returns The distance between the two points.
 */
export function getPointDistance(pointOne: [number, number], pointTwo: [number, number]): number {
  const minusX = Math.abs(pointOne[0] - pointTwo[0])
  const minusY = Math.abs(pointOne[1] - pointTwo[1])

  return Math.sqrt(minusX * minusX + minusY * minusY)
}

/**
 * Generates a UUID (version 4).
 * @param hasHyphen - Whether the UUID should include hyphens.
 * @returns A UUID string.
 */
export function uuid(hasHyphen: boolean): string {
  return (
    hasHyphen ? 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' : 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'
  ).replace(/[xy]/g, function (c) {
    const r = (Math.random() * 16) | 0
    const v = c === 'x' ? r : (r & 0x3) | 0x8
    return v.toString(16)
  })
}
